// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: xguo

#pragma once

// Include all the external dependencies

////////////////////////////////////////////////////////////
// Utils, no namespace
#include "coin2/base/config/app_config.h"
#include "coin2/base/hostname_util.h"
#include "coin2/base/log.h"
#include "coin2/base/proto_util.h"
#include "coin2/base/string_util.h"
#include "coin2/exchange/base/api_base/asio_http_context.h"
#include "coin2/exchange/base/api_base/base_auth.h"
#include "coin2/exchange/base/api_base/raw_subscriber.h"
#include "coin2/exchange/base/api_util/auth_key.h"
#include "coin2/exchange/base/api_util/zlib_decompress.h"
#include "coin2/exchange/util/json_util.h"

////////////////////////////////////////////////////////////
// External header files
#include "coin/proto/coin_order_enums.pb.h"
#include "coin/proto/coin_order_gateway.pb.h"
#include "coin/proto/coin_query.pb.h"
#include "coin/proto/symbology.pb.h"
#include "coin2/exchange/order/connection.pb.h"
#include "coin2/exchange/order/gateway.pb.h"
#include "coin2/exchange/order/system.pb.h"

namespace coin2::exchange::base::order {

// Imported external types
using coin::proto::AccountBalance;
using coin::proto::AccountPosition;
using coin::proto::CurrencyBalance;
using coin::proto::ExchangeType;
using coin::proto::FillInfo;
using coin::proto::MarketType;
using coin::proto::OrderContextProto;
using coin::proto::OrderDirection;
using coin::proto::OrderDuration;
using coin::proto::OrderEvent;
using coin::proto::OrderExecutionProto;
using coin::proto::OrderGatewayConfig;
using coin::proto::OrderGatewayLog;
using coin::proto::OrderInfo;
using coin::proto::OrderSpecProto;
using coin::proto::RawMessageProto;
// using coin::proto::OrderInfoBundle;
// using coin::proto::OrderRequest;
// using coin::proto::OrderResponse;
using coin::proto::OrderSide;
using coin::proto::OrderSide_Name;
using coin::proto::OrderState;
using coin::proto::OrderSubsystemInfo;
// using coin::proto::OrderSystemConfig;
using coin::proto::OrderErrorCode;
using coin::proto::OrderExecutionProto;
using coin::proto::OrderSubTopicId;
using coin::proto::OrderTriadState;
using coin::proto::OrderType;
using coin::proto::OrderUpdateType;
using coin::proto::ProductPosition;
using coin::proto::RestQueryProto;
using coin::proto::TradeSide;

// using OrderSpec = coin::proto::OrderInfo;
using ProductOrderBundle = coin::proto::ProductOrderBundle;
using ProductOrderElement = coin::proto::ProductOrderElement;
using ProductFillBundle = coin::proto::ProductFillBundle;
using SubmitOrderResponse = coin::proto::SubmitOrderResponse;
using CancelOrderResponse = coin::proto::CancelOrderResponse;
using SubmitOrderResponseBundle = coin::proto::SubmitOrderResponseBundle;
using CancelOrderResponseBundle = coin::proto::CancelOrderResponseBundle;
using LogType = coin::proto::OrderGatewayLog::LogType;

using coin2::exchange::order::OrderManagerConfig;
using coin2::exchange::order::OrderSystemConfig;

// conversion
using ConversionElement = coin::proto::ConversionElement;
using ConversionBundle = coin::proto::ConversionBundle;

}  // namespace coin2::exchange::base::order

////////////////////////////////////////////////////////////
// symbology
#include "coin2/exchange/base/symbology/currency.h"
#include "coin2/exchange/base/symbology/product.h"
#include "coin2/exchange/base/symbology/product_info.h"
#include "coin2/exchange/factory/symbology/product.h"

namespace coin2::exchange::base::order {

using coin2::exchange::base::symbology::ICurrency;
using coin2::exchange::base::symbology::IProduct;
using coin2::exchange::base::symbology::IProductHolder;
using coin2::exchange::base::symbology::IProductInfo;

}  // namespace coin2::exchange::base::order

////////////////////////////////////////////////////////////
// async executor
#include "coin2/exchange/base/executor/archive_executor.h"
#include "coin2/exchange/base/executor/live_executor.h"
#include "coin2/exchange/base/executor/packet.h"
#include "coin2/exchange/base/executor/topic_publisher.h"

namespace coin2::exchange::base::order {

using coin2::exchange::base::executor::ArchiveSyncExecutor;
using coin2::exchange::base::executor::IPacketSubscriber;
using coin2::exchange::base::executor::LiveAsyncExecutor;
using coin2::exchange::base::executor::TopicRecordUpdate;

}  // namespace coin2::exchange::base::order

////////////////////////////////////////////////////////////
// logger
#include "coin2/exchange/base/log/order_logger.h"

////////////////////////////////////////////////////////////
// misc
#include "coin2/base/time.h"
#include "coin2/exchange/base/api_base/asio_http_driver.h"
#include "coin2/exchange/base/market/market_exchange_api.h"
#include "coin2/exchange/di/constant.h"
#include "coin2/feed/mgr/system.h"

namespace coin2::exchange::base::order {
using coin2::exchange::base::market::MarketExchangeApi;
}

using namespace coin2::exchange::base::market;
using namespace coin2::exchange;
using coin::proto::OrderGatewayLog;
